package com.medusa.aps.business.modules.security.mp.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medusa.aps.business.common.security.model.bean.SecureUser;
import com.medusa.aps.business.common.security.model.enums.Roles;
import com.medusa.aps.business.common.security.resource.helper.ISecurity;
import com.medusa.aps.business.global.model.exception.GlobalException;
import com.medusa.aps.business.model.enums.MenuType;
import com.medusa.aps.business.model.enums.State;
import com.medusa.aps.business.model.pagination.Page;
import com.medusa.aps.business.modules.security.model.SecureExtra;
import com.medusa.aps.business.modules.security.model.input.UserQueryPara;
import com.medusa.aps.business.modules.security.model.output.UserInfoVO;
import com.medusa.aps.business.modules.security.model.output.UserRoleVO;
import com.medusa.aps.business.modules.security.model.output.UserVO;
import com.medusa.aps.business.modules.security.mp.entity.*;
import com.medusa.aps.business.modules.security.mp.mapper.RoleMenuMapper;
import com.medusa.aps.business.modules.security.mp.mapper.UserMapper;
import com.medusa.aps.business.modules.security.mp.service.IMenuService;
import com.medusa.aps.business.modules.security.mp.service.IRoleService;
import com.medusa.aps.business.modules.security.mp.service.IUserRoleService;
import com.medusa.aps.business.modules.security.mp.service.IUserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author xianhui.yu
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private IUserService userService;
    @Resource
    private IRoleService roleService;
    @Resource
    private IUserRoleService userRoleService;
    @Resource
    private IMenuService menuService;
    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public Page<UserVO> listPage(UserQueryPara userQueryPara) {
        return userMapper.selectUsers(userQueryPara);
    }

    @Override
    public UserInfoVO getCurrentUserInfo() {
        SecureUser<SecureExtra> secureUser = ISecurity.userMust();
        UserInfoVO userInfo = new UserInfoVO();
        Long userId = secureUser.getId();
        Set<Roles> userRoles = secureUser.getRoles();
        userInfo.setId(userId)
                .setUsername(secureUser.getUsername())
                .setJobNumber(secureUser.getExtra().getJobNumber())
                .setPhone(secureUser.getMobile())
                .setEmail(secureUser.getEmail())
                .setPosition(secureUser.getExtra().getPosition())
                .setUserRoles(userRoles)
                .setRemarks(secureUser.getExtra().getRemarks());

        //查询某个用户的角色
        List<Role> roles = userRoleService.selectRoleByUserId(userId);
        if (CollUtil.isEmpty(roles)) {
            return userInfo;
        }
        userInfo.setRoles(roles.stream().map(Role::getName).collect(Collectors.toSet()));
        //如果是超管 直接放行
        if (userRoles.contains(Roles.SUPER_ADMIN)) {
            return userInfo;
        }
        userInfo.setButtons(
                secureUser.getPerms()
                        .stream()
                        .map(MenuType.BUTTON::convertPerm)
                        .collect(Collectors.toSet())
        );
        //查询菜单权限
        Set<Integer> roleIds = roles.stream().map(Role::getId).collect(Collectors.toSet());
        List<Menu> menus = menuService.lambdaQuery()
                .select(Menu::getPath)
                .eq(Menu::getState, State.ENABLE)
                .eq(Menu::getType, MenuType.MENU)
                .exists("SELECT 1 FROM sys_role_menu WHERE sys_role_menu.menu_id = sys_menu.id AND sys_role_menu.role_id IN (" + CollUtil.join(roleIds, ",") + ")")
                .list();
        if (CollectionUtils.isEmpty(menus)) {
            return userInfo;
        }
        return userInfo.setMenus(
                menus.stream()
                        .map(Menu::getPath)
                        .collect(Collectors.toSet())
        );
    }

    /**
     * 查询成员列表基本信息
     *
     * @param userQueryPara 查询参数
     * @return 成员列表基本信息
     */
    @Override
    public Page<User> userList(UserQueryPara userQueryPara) {
        String userNameAndJobNumber = userQueryPara.getUserNameAndJobNumber();
        return userService.lambdaQuery()
                //排除超管
                .notExists("SELECT 1 FROM sys_user_role WHERE sys_user_role.user_id = sys_user.id AND sys_user_role.role_id = {0}", Roles.SUPER_ADMIN.getRoleId())
                .select(User::getId, User::getUsername, User::getJobNumber, User::getPhone)
                .like(StringUtils.hasText(userQueryPara.getUsername()), User::getUsername, userQueryPara.getUsername())
                .like(StringUtils.hasText(userQueryPara.getJobNumber()), User::getJobNumber, userQueryPara.getJobNumber())
                .and(
                        StringUtils.hasText(userNameAndJobNumber),
                        qw ->
                                qw.like(User::getUsername, userNameAndJobNumber)
                                        .or()
                                        .like(User::getJobNumber, userNameAndJobNumber)
                ).page(userQueryPara);
    }

    /**
     * 获取成员详细信息
     *
     * @param userId 用户id
     * @return 成员详细信息
     */
    @Override
    public UserVO getUserById(Long userId) {
        User user = userMapper.selectById(userId);
        UserVO userVO = new UserVO();
        if (user == null) {
            return userVO;
        }
        userVO.setProperties(user);
        List<Integer> roleIds = userRoleService.lambdaQuery()
                .select(UserRole::getRoleId)
                .eq(UserRole::getUserId, userId)
                .list().stream()
                .map(UserRole::getRoleId).toList();
        if (CollectionUtils.isEmpty(roleIds)) {
            return userVO;
        }
        userVO.setUserRoles(
                roleService.lambdaQuery()
                        .select(Role::getId, Role::getName)
                        .in(Role::getId, roleIds)
                        .list().stream()
                        .map(role -> new UserRoleVO()
                                .setRoleId(role.getId())
                                .setRoleName(role.getName())).toList()
        );
        return userVO;
    }

    @Override
    public Boolean hasPermission(String phone) {
        User user = userService.lambdaQuery()
                .select(User::getId)
                .eq(User::getPhone, phone)
                .one();
        if (user == null) {
            throw new GlobalException("用户不存在");
        }
        Set<Integer> roleIds = userRoleService.lambdaQuery()
                .select(UserRole::getRoleId)
                .eq(UserRole::getUserId, user.getId())
                .list()
                .stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(roleIds)) {
            return false;
        }
        //包含超管角色返回有权限
        if (roleIds.contains(Roles.SUPER_ADMIN.getRoleId().intValue())) {
            return true;
        }
        Long count = roleMenuMapper.selectCount(
                new LambdaQueryWrapper<RoleMenu>()
                        .in(RoleMenu::getRoleId, roleIds)
        );
        return count > 0;

    }

}
